﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Authorization;
using Abp.Authorization.Users;
using Abp.Configuration;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Events.Bus;
using Abp.Organizations;
using Abp.Runtime.Caching;
using Vecen.BangChuang.Authorization.Roles;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Vecen.BangChuang.BangChuang.DomainServices.EventHandlers.EventDatas;

namespace Vecen.BangChuang.Authorization.Users {
    public class UserManager: AbpUserManager<Role, User> {
        private readonly IEventBus _eventBus;

        public UserManager(RoleManager roleManager,
            UserStore store,
            IOptions<IdentityOptions> optionsAccessor,
            IPasswordHasher<User> passwordHasher,
            IEnumerable<IUserValidator<User>> userValidators,
            IEnumerable<IPasswordValidator<User>> passwordValidators,
            ILookupNormalizer keyNormalizer,
            IdentityErrorDescriber errors,
            IServiceProvider services,
            ILogger<UserManager<User>> logger,
            IPermissionManager permissionManager,
            IUnitOfWorkManager unitOfWorkManager,
            ICacheManager cacheManager,
            IRepository<OrganizationUnit, long> organizationUnitRepository,
            IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
            IOrganizationUnitSettings organizationUnitSettings,
            ISettingManager settingManager,
            IEventBus eventBus): base(roleManager, store, optionsAccessor, passwordHasher, userValidators,
            passwordValidators, keyNormalizer, errors, services, logger, permissionManager, unitOfWorkManager,
            cacheManager, organizationUnitRepository, userOrganizationUnitRepository, organizationUnitSettings,
            settingManager) {
            _eventBus = eventBus;
        }

        public override Task<IdentityResult> CheckDuplicateUsernameOrEmailAddressAsync(long? expectedUserId,
            string userName,
            string emailAddress) {
            if(!string.IsNullOrWhiteSpace(emailAddress)) {
                return base.CheckDuplicateUsernameOrEmailAddressAsync(expectedUserId, userName, emailAddress);
            }
            return Task.Run(() => IdentityResult.Success);
        }

        public override async Task<IdentityResult> DeleteAsync(User user) {
            await _eventBus.TriggerAsync(new UserDeleteBeforeEventData() {UserId = user.Id});
            return await base.DeleteAsync(user);
        }
    }
}